﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using GestionNewsLetters.Models.Dao;
using System.Data;
using System.Text.RegularExpressions;
using System.Data.Objects;

namespace GestionNewsLetters.Controllers
{
    /// <summary>
    /// Controller to mangage newsletter subscription
    /// </summary>
    public class NewsletterController : Controller
    {
        //
        // GET: /Newsletter/

        public ActionResult Index()
        {
            return Redirect("http://www.laboratoire-microsoft.org/");
        }

        /// <summary>
        /// Insert a new user in the database and sends back a json state (ie succeed or not)
        /// Insère un nouveau mail dans la base de données et renvoie un état en json.
        /// </summary>
        /// <param name="mail"></param>
        /// <returns></returns>
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult RegisterUser(string mail)
        {
            string message;
            bool valid;

            string regexString = @"^[a-zA-Z\.\-_]+@([a-zA-Z\.\-_]+\.)+[a-zA-Z]{2,4}$";

            Regex rgx = new Regex(regexString, RegexOptions.IgnoreCase);

            //On vérifie le mail
            //We verifie the mail
            if(mail.Length >5 && rgx.Match(mail).Length == mail.Length)
            {

                //On vérifie si l'adresse email existe déjà
                //We verifie if email already exists in database
                using (DbMsEntities dbNewsletterE = new DbMsEntities())
                {

                    
                        var query1 = dbNewsletterE
                           .AUTEURS
                           .Where(c => c.MAIL == mail)
                           .Count();
                    

                    //Si on n'a pas de correspondance pour le mail dans la bdd
                    //If mail doesn't already exist
                        if (query1.GetType() == typeof(Int32) && query1 == 0)
                        {


                            //On crée l'objet de type AUTEUR
                            //We create an new AUTEUR (user who subscibe to the newsletter)
                            AUTEUR user = new AUTEUR()
                            {
                                NEWSLETTER = false,
                                MAIL = mail,
                                PASSWORD = string.Empty
                                //Token = System.Guid.NewGuid()
                            };

                            //On insère le mail en base de données
                            //We insert the user in database
                    
                            dbNewsletterE.AUTEURS.Context.AddObject("DbMsEntities.AUTEURS", user);
                            dbNewsletterE.SaveChanges();

                            message = "Inscription réussie!";
                            valid = true;

                        }
                        //Si le mail existe déjà
                            //if the mail already exists
                        else
                        {
                            message = "Vous êtes déjà inscrit.";
                            valid = false;
                        }
                }


                
            }
            else
            {
                //If email is not valid
                message = "Adresse email invalide.";
                valid = false;
            }

            return Json(new { message = message, valid = valid }, JsonRequestBehavior.DenyGet);
        }

        /// <summary>
        /// subscribe or unsubscribe an existing user to the newsletter
        /// </summary>
        /// <param name="token">token (here it's an integer, but you can easily change code so it'll be a GUID). Was a GUID originally.</param>
        /// <param name="mail">user mail</param>
        /// <param name="inscription">true: subscribe, false: unsuscribe</param>
        /// <returns></returns>
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Inscription(int? token, string mail, bool? inscription)
        {

            //If params are null, we display the form
            //Si les paramètres sont nuls, ont affiche la vue avec le formulaire
            if (token == null || mail == null || inscription == null)
            {
                //We are saving the token and the mail in ViewData so we can display them in View
                //On sauve token et mail dans ViewData pour pouvoir les utiliser dans la vue
                ViewData["token"] = token;
                ViewData["mail"] = mail;

                //If we alread have mail and token, the user can not modify them client side. Usually happens when user clicks on 
                //unsubscribe link in the newsletter
                //Si on a reçu les infos sur l'adresse mail et le token, on empêche l'utilisateur de les ressaisir
                if (mail != null & token != null)
                    ViewData["InputProperties"] = new Dictionary<string, object>() { {"readonly", true}, {"class","disabledControl"} };
                
                return View("FormulaireInscription");
            }
            else
            {
                //adresseMail will contain token, mail and a boolean indicating if the user subscribed or not
                //adresseMail contiendra le token, le mail, et l'inscription de l'utilisateur
                Object adresseMail = null;

                using (DbMsEntities dbNewsletterE = new DbMsEntities())
                {
                    //We get AdresseMail object associated to this mail
                    //On récupère l'objet AdresseMail associé à ce mail
                    IEnumerable<KeyValuePair<string, object>> entityKeyValues =
                        new KeyValuePair<string, object>[] {
                new KeyValuePair<string, object>("MAIL", mail)};

                    EntityKey key = new EntityKey("DbMsEntities.AUTEURS", entityKeyValues);

                    //If we have a match and the id matches too
                    //Si on a une correspondance pour le mail dans la bdd et que le token correspond
                    if (dbNewsletterE.TryGetObjectByKey(key, out adresseMail) && ((AUTEUR)adresseMail).ID == token)
                    {
                        //On enregistre l'inscription ou la désinscription de l'utilisateur à la newsletter
                        ((AUTEUR)adresseMail).NEWSLETTER = inscription.Value;
                        dbNewsletterE.SaveChanges();

                    }
                        //If the token and/or the mail don't match
                    //Si le token et/ou le mail ne corespondent pas
                    else
                    {
                        ModelState.AddModelError("", "Le token et l'adresse mail ne correspondent pas.");
                        return View("FormulaireInscription");
                    }
                }
            }
            //Subscibe/unsubscribe action succeeded, we tell the user
            //Si on arrive là, la désinscription ou l'inscription a réussie.
            //On l'annonce à l'utilisateur
            if (inscription == true)
                ViewData["message"] = "Votre inscription à la newsletter du Laboratoire Microsoft a été prise en compte";
            else
                ViewData["message"] = "Votre désinscription à la newsletter du Laboratoire Microsoft a été prise en compte";

            ViewData["redirectionLaboMs"] = true;

            return View();
        }

        //Unknown actions
        //Gestion des actions inconnues
        protected override void HandleUnknownAction(string actionName)
        {
            if (this.ActionInvoker.InvokeAction(this.ControllerContext, "Index"))
                return;
            base.HandleUnknownAction(actionName);
        }

    }
}
